home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr11
/
pctv4n2.zip
/
TELBOOK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-09
|
8KB
|
359 lines
/***************************************************************
* *
* TELBOOK1.C - *
* Example using base 40 compression/decompression routines *
* by Al Williams *
* *
***************************************************************/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <conio.h>
#include <ctype.h>
#include <stdlib.h>
#include "b40.h"
/* main table of phone numbers - 1000 maximum */
struct phentry
{
char *text;
unsigned char siz;
} phonelst[1000];
/* first free entry in phonelst */
int last=0;
/* buffers for input and conversion */
char inbuf[81];
char cvtbuf[81];
int menu(char *fn);
void sdelete(char *p);
void linein(char *inbuf,size_t siz,FILE *f);
/* command functions */
void list(FILE *f);
void disp(FILE *f,int i,char *cvtbuf);
void new(int id);
void save(char *fn);
void sdelete(char *p);
void replace(void);
void find(void);
void telsort(void);
/********************************************/
main(int argc,char *argv[])
{
FILE *f;
if (argc>2||argv[1][0]=='?'||argv[1][1]=='?')
{
printf("TELBOOK by Al Williams\n");
printf("usage: TELBOOK phonefile\n");
exit(1);
}
/* open file */
f=fopen(argv[1],"rb");
/* if data file present, read it in */
if (f)
{
unsigned int n;
while (!feof(f))
{
/* read count */
n=getc(f);
if (n==(unsigned int)EOF) break;
/* read string in */
fread(inbuf,1,n,f);
/* allocate space and copy it in */
phonelst[last].siz=n;
phonelst[last].text=malloc(n);
memcpy(phonelst[last++].text,inbuf,n);
}
fclose(f);
}
while (1) menu(argv[1]);
}
/****************** main menu */
int menu(char *fn)
{
int cmd;
printf(" -- MAIN MENU --\n"
"L - List phone book\n"
"P - Print phone book\n"
"N - New entry\n"
"R - Replace entry\n"
"F - Find entry\n"
"S - Save phone book\n"
"O - Order (sort) phone book\n"
"X - eXit\nYour choice: ");
cmd=getch();
if (!cmd) { getch(); return; }
putch(cmd);
putch('\n');
putch('\r');
switch (toupper(cmd))
{
case 'L': list(stdout);
break;
case 'P':
list(stdprn);
break;
case 'N': new(-1);
break;
case 'S': save(fn);
break;
case 'R': replace();
break;
case 'F': find();
break;
case 'O': telsort();
break;
case 'X': exit(0);
}
return;
}
/********************************************
/* Read a line in -- shift to upper and strip the \n and process out
( ) and -. Also, eat blanks after a ) character */
void linein(char *inbuf,size_t siz,FILE *f)
{
char *p;
fflush(f);
fgets(inbuf,siz,f);
/* remove \n at end if present */
p=strchr(inbuf,'\n');
if (p) *p='\0';
/* shift to upper case */
strupr(inbuf);
/* remove ( */
while (p=strchr(inbuf,'(')) sdelete(p);
/* remove ) and trailing blanks */
while (p=strchr(inbuf,')'))
{
sdelete(p);
while (isspace(*p)) sdelete(p);
}
/* remove - */
while (p=strchr(inbuf,'-')) sdelete(p);
}
/********************************************
/* list all entries to file f */
void list(FILE *f)
{
int i;
int total=0;
for (i=0;i<last;i++)
{
/* decode line */
b40_decode(cvtbuf,phonelst[i].text,phonelst[i].siz);
total+=strlen(cvtbuf);
/* call disp to print it out */
disp(f,i,cvtbuf);
}
fprintf(f,"%d bytes\n",total);
}
/********************************************
/* Print line number i (decoded in cvtbuf) to file f */
void disp(FILE *f,int i,char *cvtbuf)
{
char *token=NULL,telno[33],*tp=telno;
int l;
/* print entry number */
fprintf(f,"[%03d] ",i);
/* get tokens */
while (token=strtok(token?NULL:cvtbuf," \t"))
{
int l=strlen(token);
/* if token is number -- try to format it as a phone number */
if (strspn(token,"0123456789")==l)
{
/* if l==10 then (XXX) YYY-ZZZZ */
if (l==10)
{
*tp++='(';
memcpy(tp,token,3);
*(tp+=3)=')';
*(++tp)=' ';
tp++;
token+=3;
}
/* if l==7 then YYY-ZZZZ */
if (l==10||l==7)
{
memcpy(tp,token,3);
*(tp+=3)='-';
strcpy(++tp,token+3);
/* print formatted telephone number and get new token */
fprintf(f,"%s ",telno);
continue;
}
}
/* print non-phone number tokens */
fprintf(f,"%s ",token);
}
putc('\n',f);
return;
}
/********************************************
/* make new entry if id==-1 then add to end
else replace entry #id. If id is past
end, then pretend id==-1 */
void new(int id)
{
char *p;
int n,c;
if (id>=last) id=-1;
/* if replacing, confirm */
if (id!=-1)
{
/* print entry to replace */
b40_decode(cvtbuf,phonelst[id].text,phonelst[id].siz);
disp(stdout,id,cvtbuf);
/* prompt */
printf("Change this entry (Y/N): ");
do
{
c=getche();
if (!c)
{
getch();
continue;
}
c=toupper(c);
} while (c!='N'&&c!='Y');
putchar('\n');
/* if no confirm, quit */
if (c=='N') return;
}
/* if previous entry exists, free its memory */
if (id!=-1&&phonelst[id].text) free(phonelst[id].text);
/* get new entry */
printf("New Entry:\n");
linein(inbuf,sizeof(inbuf),stdin);
/* encode entry */
n=b40_encode(cvtbuf,inbuf);
/* enter into table */
phonelst[id==-1?last:id].siz=n;
phonelst[id==-1?last:id].text=malloc(n);
memcpy(phonelst[id==-1?last++:id].text,cvtbuf,n);
}
/********************************************
/* save to file */
void save(char *fn)
{
unsigned int i,total=0;
FILE *f;
f=fopen(fn,"wb");
if (!f) { perror(fn); exit(1); }
/* loop through entries */
for (i=0;i<last;i++)
{
/* write size */
putc(phonelst[i].siz,f);
/* write entry */
fwrite(phonelst[i].text,1,phonelst[i].siz,f);
/* update total */
total+=phonelst[i].siz+1;
}
fclose(f);
printf("Saved %s (%u bytes)\n",fn,total);
}
/********************************************
/* This routine deletes the character at p from a string.
As written, it knows that strcpy() moves characters
from lower addresses first -- behavior that might
not be true on all systems. That is why sdelete()
is a seperate function -- you may want to change it. */
void sdelete(char *p)
{
strcpy(p,p+1);
}
/********************************************
/* replace an entry */
void replace()
{
char ans[4];
while (1)
{
printf("Entry (? for list): ");
*ans='\0';
fgets(ans,sizeof(ans),stdin);
if (*ans=='\n') return;
/* if ? print list */
if (*ans=='?')
{
list(stdout);
continue;
}
/* call new to make entry */
new(atoi(ans));
break;
}
}
/********************************************
/* Find entries that match an entered substring */
void find()
{
int i,len;
printf("Search for: ");
linein(inbuf,sizeof(inbuf),stdin);
if (!*inbuf) return;
len=strlen(inbuf);
/* search for entry */
for (i=0;i<last;i++)
{
/* decode */
b40_decode(cvtbuf,phonelst[i].text,phonelst[i].siz);
/* only look at substring */
if (!strncmp(cvtbuf,inbuf,len))
disp(stdout,i,cvtbuf); /* display matches */
}
}
/********************************************
/* Function to support qsort() */
static int sortfunc(const void *in1,const void *in2)
{
/* decode and compare */
struct phentry *e1, *e2;
e1=(struct phentry *)in1;
e2=(struct phentry *)in2;
b40_decode(cvtbuf,e1->text,e1->siz);
b40_decode(inbuf,e2->text,e2->siz);
return strcmp(cvtbuf,inbuf);
}
/********************************************
/* Sort function */
void telsort()
{
qsort(phonelst,last,sizeof(phonelst[0]),sortfunc);
}